/**
 * Copyright 2019 吉鼎科技.

 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.easyplatform.engine.cmd.list;

import cn.easyplatform.contexts.ListContext;
import cn.easyplatform.contexts.RecordContext;
import cn.easyplatform.contexts.WorkflowContext;
import cn.easyplatform.dos.FieldDo;
import cn.easyplatform.dos.Record;
import cn.easyplatform.engine.runtime.datalist.DataListUtils;
import cn.easyplatform.entities.beans.table.TableBean;
import cn.easyplatform.interceptor.AbstractCommand;
import cn.easyplatform.interceptor.CommandContext;
import cn.easyplatform.lang.Lang;
import cn.easyplatform.lang.Strings;
import cn.easyplatform.messages.request.ListCreateRequestMessage;
import cn.easyplatform.messages.response.SimpleResponseMessage;
import cn.easyplatform.messages.vos.datalist.ListCreateVo;
import cn.easyplatform.messages.vos.datalist.ListHeaderVo;
import cn.easyplatform.type.*;
import cn.easyplatform.util.MessageUtils;
import cn.easyplatform.util.RuntimeUtils;

import java.util.List;

/**
 * @author <a href="mailto:davidchen@epclouds.com">littleDog</a> <br/>
 * @since 2.0.0 <br/>
 */
public class CreateCmd extends AbstractCommand<ListCreateRequestMessage> {

    /**
     * @param req
     */
    public CreateCmd(ListCreateRequestMessage req) {
        super(req);
    }

    @Override
    public IResponseMessage<?> execute(CommandContext cc) {
        ListCreateVo cv = req.getBody();
        WorkflowContext ctx = cc.getWorkflowContext();
        ListContext lc = ctx.getList(cv.getId());
        TableBean tb = cc.getEntity(lc.getBean().getTable());
        if (tb == null)
            return MessageUtils.entityNotFound(EntityType.TABLE.getName(), lc
                    .getBean().getTable());
        RecordContext rc = null;
        if (cv.getCopyKeys() != null) {
            RecordContext from = lc.getRecord(cv.getCopyKeys());
            if (from == null) {
                from = lc.createRecord(cv.getCopyKeys(), DataListUtils.getRecord(cc, lc, cv.getCopyKeys()));
                from.setParameter("814", 'R');
                lc.appendRecord(from);
            }
            rc = from.create();
            rc.setData(from.getData().clone());
            if (tb.isAutoKey())
                rc.setValue(tb.getKey().get(0),
                        cc.getIdGenerator().getNextId(tb.getId()));
        } else
            rc = lc.createRecord(RuntimeUtils.createRecord(cc, tb,
                    tb.isAutoKey()));
        List<ListHeaderVo> headers = lc.getHeaders();
        int size = headers.size();
        for (int i = 0; i < size; i++) {
            ListHeaderVo hv = headers.get(i);
            if (Strings.isBlank(hv.getField()) && hv.getType() != null) {
                FieldDo var = new FieldDo(hv.getType());
                var.setName(hv.getName());
                var.setScope(ScopeType.PRIVATE);
                if (hv.getType() == FieldType.NUMERIC) {
                    var.setDecimal(2);
                    var.setLength(19);
                }
                rc.setVariable(var);
            }
        }
        if (!Strings.isBlank(lc.getBeforeLogic())) {
            RecordContext[] rcs = new RecordContext[2];
            if (!Strings.isBlank(lc.getHost())) {
                ListContext fc = ctx.getList(lc.getHost());
                if (fc == null)
                    return MessageUtils.dataListNotFound(lc.getHost());
                RecordContext r = fc.getRecord(cv.getFromKeys());
                if (r == null && fc.getType().equals(Constants.CATALOG)) {
                    Record record = DataListUtils.getRecord(cc, fc,
                            cv.getFromKeys());
                    r = fc.createRecord(cv.getFromKeys(), record);
                    r.setParameter("815", false);
                    r.setParameter("814", "R");
                    fc.appendRecord(r);
                }
                if (r == null)
                    return MessageUtils.recordNotFound(fc.getBean().getTable(),
                            Lang.concat(cv.getFromKeys()).toString());
                rcs[0] = r;
            } else
                rcs[0] = ctx.getRecord();
            rcs[1] = rc;
            String code = RuntimeUtils.eval(cc, lc.getBeforeLogic(), rcs);
            if (!code.equals("0000"))
                return MessageUtils.byErrorCode(cc, rc, ctx.getId(), code);
        }
        rc.setParameter("814", "C");
        rc.setParameter("815", true);
        lc.appendRecord(rc, !tb.isAutoKey());
        if (!Strings.isBlank(lc.getOnRow())) {
            String code = RuntimeUtils.eval(cc, lc.getOnRow(), rc);
            if (!code.equals("0000"))
                return MessageUtils.byErrorCode(cc, rc, ctx.getId(), code);
        }
        ListRowVo rv = new ListRowVo(rc.getKeyValues(), DataListUtils.wrapRow(
                cc, lc, rc), rc.getParameterAsBoolean("853"));
        return new SimpleResponseMessage(rv);
    }

    @Override
    public String getName() {
        return "list.Create";
    }

}
